package com.lsfb.signsys.view.BottomNavView;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.support.design.internal.*;
import android.support.transition.AutoTransition;
import android.support.transition.TransitionManager;
import android.support.transition.TransitionSet;
import android.support.v4.util.Pools;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v7.view.menu.MenuBuilder;
import android.support.v7.view.menu.MenuItemImpl;
import android.support.v7.view.menu.MenuView;
import android.util.AttributeSet;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import static com.lsfb.signsys.view.BottomNavView.BottomNavigationMenu.MAX_ITEM_COUNT;

/**
 * Created by zgscwjm on 2018/3/27.
 */

public class BottomNavigationMenuView extends ViewGroup implements MenuView {

    /**
     * 这个应该是过度时间
     */
    private static final long ACTIVE_ANIMATION_DURATION_MS = 115L;


    /**
     * 应该是过度动画
     */
    private final TransitionSet mSet;


    private final int mInactiveItemMaxWidth;
    private final int mInactiveItemMinWidth;
    private final int mActiveItemMaxWidth;
    private final int mItemHeight;


    private boolean mShiftingMode = true;

    /**
     * 按钮集合
     */
    private BottomNavigationItemBadgeView[] mButtons;

    private int mSelectedItemId = 0;
    /**
     * 这里应该是菜单宽度集合
     */
    private int[] mTempChildWidths;
    /**
     * 点击监听
     */
    private final OnClickListener mOnClickListener;

    //这个是一个缓存池
    private final Pools.Pool<BottomNavigationItemBadgeView> mItemPool = new Pools.SynchronizedPool<>(MAX_ITEM_COUNT);

    /**
     * 执行者
     */
    private BottomNavigationPresenter mPresenter;

    /**
     * 菜单建造者
     */
    private MenuBuilder mMenu;

    /**
     * 选中的位置
     */
    private int mSelectedItemPosition = 0;


    /**
     * 图标颜色 集合
     */
    private ColorStateList mItemIconTint;
    private ColorStateList mItemTextColor;

    /**
     * 背景色资源
     */
    private int mItemBackgroundRes;

    /**
     * 滑动模式开启数
     */
    private int mShiftingModeSize=4;

    public int getShiftingModeSize() {
        return mShiftingModeSize;
    }

    public void setShiftingModeSize(int ShiftingModeSize) {
        this.mShiftingModeSize = ShiftingModeSize;
    }

    public BottomNavigationMenuView(Context context) {
        this(context, null);
    }

    @SuppressLint("RestrictedApi")
    public BottomNavigationMenuView(Context context, AttributeSet attrs) {
        super(context, attrs);

        //得到样式资源
        final Resources res = getResources();
        //设置最大宽
        mInactiveItemMaxWidth = res.getDimensionPixelSize(
                android.support.design.R.dimen.design_bottom_navigation_item_max_width);

        //设置最小宽度
        mInactiveItemMinWidth = res.getDimensionPixelSize(
                android.support.design.R.dimen.design_bottom_navigation_item_min_width);

        //设置活跃的item的最大宽度
        mActiveItemMaxWidth = res.getDimensionPixelSize(
                android.support.design.R.dimen.design_bottom_navigation_active_item_max_width);

        //设置item的高度
        mItemHeight = res.getDimensionPixelSize(android.support.design.R.dimen.design_bottom_navigation_height);


        mSet = new AutoTransition();
        mSet.setOrdering(TransitionSet.ORDERING_TOGETHER);
        mSet.setDuration(ACTIVE_ANIMATION_DURATION_MS);
        mSet.setInterpolator(new FastOutSlowInInterpolator());
        //这个是什么效果?
        mSet.addTransition(new TextScale());

        mOnClickListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                final BottomNavigationItemView itemView = (BottomNavigationItemView) v;
                MenuItem item = itemView.getItemData();
                if (!mMenu.performItemAction(item, mPresenter, 0)) {
                    item.setChecked(true);
                }
            }
        };

        //这里换成自己的
        mTempChildWidths = new int[MAX_ITEM_COUNT];

    }

    @Override
    public void initialize(MenuBuilder menu) {
        //初始化 装填菜单建造者
        mMenu = menu;
    }

    @Override
    public int getWindowAnimations() {
        return 0;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        final int count = getChildCount();
        final int width = right - left;
        final int height = bottom - top;
        int used = 0;
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() == GONE) {
                continue;
            }
            if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
                child.layout(width - used - child.getMeasuredWidth(), 0, width - used, height);
            } else {
                child.layout(used, 0, child.getMeasuredWidth() + used, height);
            }
            used += child.getMeasuredWidth();
        }
    }


    //这里是计算大小
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int width = MeasureSpec.getSize(widthMeasureSpec);

        final int count = getChildCount();

        final int heightSpec = MeasureSpec.makeMeasureSpec(mItemHeight, MeasureSpec.EXACTLY);

        //两种模式
        if (mShiftingMode) {
            //滑动缩放模式

            final int inactiveCount = count - 1;
            final int activeMaxAvailable = width - inactiveCount * mInactiveItemMinWidth;
            final int activeWidth = Math.min(activeMaxAvailable, mActiveItemMaxWidth);
            final int inactiveMaxAvailable = (width - activeWidth) / inactiveCount;
            final int inactiveWidth = Math.min(inactiveMaxAvailable, mInactiveItemMaxWidth);
            int extra = width - activeWidth - inactiveWidth * inactiveCount;
            for (int i = 0; i < count; i++) {
                mTempChildWidths[i] = (i == mSelectedItemPosition) ? activeWidth : inactiveWidth;
                if (extra > 0) {
                    mTempChildWidths[i]++;
                    extra--;
                }
            }
        } else {
            final int maxAvailable = width / (count == 0 ? 1 : count);
            final int childWidth = Math.min(maxAvailable, mActiveItemMaxWidth);
            int extra = width - childWidth * count;
            for (int i = 0; i < count; i++) {
                mTempChildWidths[i] = childWidth;
                if (extra > 0) {
                    mTempChildWidths[i]++;
                    extra--;
                }
            }
        }

        //计算
        //xxx 这里可以优化  不需要隐藏
        int totalWidth = 0;
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() == GONE) {
                continue;
            }
            child.measure(MeasureSpec.makeMeasureSpec(mTempChildWidths[i], MeasureSpec.EXACTLY),
                    heightSpec);
            ViewGroup.LayoutParams params = child.getLayoutParams();
            params.width = child.getMeasuredWidth();
            totalWidth += child.getMeasuredWidth();
        }
        setMeasuredDimension(
                View.resolveSizeAndState(totalWidth,
                        MeasureSpec.makeMeasureSpec(totalWidth, MeasureSpec.EXACTLY), 0),
                View.resolveSizeAndState(mItemHeight, heightSpec, 0));

    }


    /**
     * 设置 图标
     *
     * @param tint
     */
    @SuppressLint("RestrictedApi")
    public void setIconTintList(ColorStateList tint) {
        mItemIconTint = tint;
        if (mButtons == null) return;
        for (BottomNavigationItemView item : mButtons) {
            item.setIconTintList(tint);
        }
    }

    public ColorStateList getmItemIconTint() {
        return mItemIconTint;
    }


    /**
     * 设置文字颜色
     *
     * @param color
     */
    @SuppressLint("RestrictedApi")
    public void setItemTextColor(ColorStateList color) {
        mItemTextColor = color;
        if (mButtons == null) return;
        for (BottomNavigationItemView item : mButtons) {
            item.setTextColor(color);
        }
    }

    public ColorStateList getItemTextColor() {
        return mItemTextColor;
    }


    public int getSelectedItemId() {
        return mSelectedItemId;
    }


    @SuppressLint("RestrictedApi")
    public void setItemBackgroundRes(int background) {
        mItemBackgroundRes = background;
        if (mButtons == null) return;
        for (BottomNavigationItemView item : mButtons) {
            item.setItemBackground(background);
        }
    }

    public int getItemBackgroundRes() {
        return mItemBackgroundRes;
    }


    public void setPresenter(BottomNavigationPresenter presenter){
        mPresenter = presenter;
    }

    /**
     * 创建菜单view
     */
    @SuppressLint("RestrictedApi")
    public void buildMenuView() {
        removeAllViews();
        if (mButtons != null) {
            for (BottomNavigationItemBadgeView item : mButtons) {
                //将按钮放到 池里面
                mItemPool.release(item);
            }
        }


        //没有菜单
        if (mMenu.size() == 0) {
            mSelectedItemId = 0;
            mSelectedItemPosition = 0;
            mButtons = null;
            return;
        }

        mButtons = new BottomNavigationItemBadgeView[mMenu.size()];

        //设置 模式 (缩进模式)
        mShiftingMode = mMenu.size() > mShiftingModeSize;


        //这里开始 设置每个 menu 的样式
        for (int i = 0; i < mMenu.size(); i++) {


            //设置更新暂停
            mPresenter.setUpdateSuspended(true);
            mMenu.getItem(i).setCheckable(true);
            mPresenter.setUpdateSuspended(false);

            //创建新的Item
            BottomNavigationItemBadgeView child = getNewItem();

            mButtons[i] = child;

            child.setIconTintList(mItemIconTint);
            child.setTextColor(mItemTextColor);
            child.setItemBackground(mItemBackgroundRes);
            child.setShiftingMode(mShiftingMode);
            child.initialize((MenuItemImpl) mMenu.getItem(i), 0);
            child.setItemPosition(i);
            child.setOnClickListener(mOnClickListener);
            addView(child);
        }

        //默认第一个被选中
        mSelectedItemPosition = Math.min(mMenu.size() - 1, mSelectedItemPosition);
        mMenu.getItem(mSelectedItemPosition).setCheckable(true);
    }


    @SuppressLint("RestrictedApi")
    public void updateMenuView() {
        @SuppressLint("RestrictedApi")
        final int menuSize = mMenu.size();
        //如果当前的菜单长度 不等于 按钮长度
        if (menuSize!=mButtons.length){
            //长度已经改变,重建菜单视图
            buildMenuView();
            return;
        }

        //得到之前的选中id
        int previousSelectedId  = mSelectedItemId;

        for (int i = 0; i < menuSize; i++) {
            @SuppressLint("RestrictedApi")
            MenuItem item = mMenu.getItem(i);
            if (item.isChecked()){
                //记录下选中的id
                mSelectedItemId = item.getItemId();
                mSelectedItemPosition = i;
            }
        }

        if (previousSelectedId != mSelectedItemId){

            // Note: this has to be called before BottomNavigationItemView#initialize().
            //这个在 BottomNavigationItemView 类中的initialize 方法之前调用
            TransitionManager.beginDelayedTransition(this,mSet);
        }


        for (int i = 0; i < menuSize; i++) {
            mPresenter.setUpdateSuspended(true);
            mButtons[i].initialize((MenuItemImpl) mMenu.getItem(i),0);
            mPresenter.setUpdateSuspended(false);
        }


    }

    /**
     * 创建新的item实例
     *
     * @return
     */
    @SuppressLint("RestrictedApi")
    private BottomNavigationItemBadgeView getNewItem() {
        BottomNavigationItemBadgeView item = mItemPool.acquire();
        if (item == null) {
//            item = new BottomNavigationItemView(getContext());
            item = new BottomNavigationItemBadgeView(getContext());
        }
        return item;
    }

    /**
     * 尝试恢复之前的选中状态
     *
     * @param itemId
     */
    public void tryRestoreSelectedItemId(int itemId) {
        @SuppressLint("RestrictedApi") final int size = mMenu.size();
        for (int i = 0; i < size; i++) {
            @SuppressLint("RestrictedApi")
            MenuItem item = mMenu.getItem(i);
            if (itemId == item.getItemId()) {
                mSelectedItemId = itemId;
                mSelectedItemPosition = i;
                item.setChecked(true);
                break;
            }
        }
    }


    public IBadge getBadge(int postion){
        if (mButtons==null){
            return null;
        }
        if (postion>mButtons.length){
            return null;
        }
        return mButtons[postion];
    }

}
